<template>
  <basic-dialog
    width="60%"
    :visible="visible"
    :showFooter="false"
    :handleClose="handleCancel"
  >
    <div>
      <div v-loading="pageLoading">
        <SetHeader
          ref="headerRef"
          :refer-cities-options="referCitiesOptions"
          :supply-cities-options="supplyCitiesList"
          :checked-supply-city-codes.sync="supplyCityCodes"
          @updateSupplyCities="updateSalesListBySupplyCities"
          @batchSet="batchSetReferInfo"
        />
        <SkusTable
          showSelectCol
          :dataSource="TableInfo.list"
          :columns="TableInfo.columns"
          :loading="TableInfo.loading"
          :selectionChange="TableInfo.setSelection"
        />
      </div>
      <div class="footer-wrap" slot="ft">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleConfirm">确定</el-button>
      </div>
    </div>
  </basic-dialog>
</template>
<script>
import BasicDialog from '@/components/BasicDialog';
import SkusTable from '@/components/skusTable';
import SetHeader from './SetHeader';
import ReferCitySelect from './ReferCitySelect';
import InputNumber from '@/components/inputNumber/inputNumber';
import { TableInfo, getCityNamesByPurchaseIneligibleRatio } from '@/utils/getUtils';
import {
  getSupplyProvinceBySupplyNoService,
  getSupplyCityByAreaCodesService,
  getPriceRatioByAreaCodeService
} from '@/api/commodity/common';
export default {
  components: {
    BasicDialog,
    SkusTable,
    SetHeader,
    ReferCitySelect,
    InputNumber
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      pageLoading: false,
      TableInfo: new TableInfo(),
      supplyCitiesList: [], // 供货城市列表集合
      referCitiesOptions: [], // 参照城市下拉集合
      supplyCityCodes: []
    }
  },
  created () {
    this.setSalesCitiesColumns()
  },
  watch: {
    visible (newVal) {
      if (newVal) this.setReferRelList()
    }
  },
  methods: {
    // 是否参照自己
    isSelfReferenced (cityInfo) {
      const isSelfReferenced = cityInfo.saleCityUuid == cityInfo.templateCityUuid // 本销售城市编码等于本参照城市编码，即参照自己
      return isSelfReferenced
    },
    // 是否主供
    isSupply (cityInfo) {
      const isSupply = this.supplyCityCodes.includes(cityInfo.saleCityUuid) // 当前城市编码存在于供货城市编码集合中，即该城市为供货城市
      return isSupply
    },
    // 获取供货城市复选列表数据
    async getSupplyCitiesList () {
      const data = { supplierCode: this.$attrs?.supplierCode }
      const res = await getSupplyProvinceBySupplyNoService(data)
      return res?.retData ?? []
    },
    // 获取销售城市表格列表数据
    async getSalesCitiesList () {
      const data = { areaCode: this.$attrs?.areaCodes }
      const res = await getSupplyCityByAreaCodesService(data)
      return res?.retData ?? []
    },
    // 设置参照相关集合
    async setReferRelList () {
      try {
        this.pageLoading = true
        const [supplyReult, salesResult] = await Promise.allSettled([this.getSupplyCitiesList(), this.getSalesCitiesList()])
        this.pageLoading = false
        this.supplyCitiesList = supplyReult.status == 'fulfilled' ? supplyReult.value : []
        const salesCitiesList = salesResult.status == 'fulfilled' ? this.getInitSalesCitiesList(salesResult.value) : []
        this.TableInfo.setList(salesCitiesList)
        this.supplyCityCodes = supplyReult.value.map(item => item.cityCode) // 供货城市编码集合
        this.referCitiesOptions = salesCitiesList.map(item => ({
          value: item.saleCityUuid,
          label: item.saleCityName
        }))
      } catch (err) {
        this.pageLoading = false
      }
    },
    // 获取初始化后的销售城市列表
    getInitSalesCitiesList (list) {
      const initList = list.map(item => ({
        saleAreaUuid: item.areaCode, // 业务区域编码
        saleAreaName: item.areaName, // 业务区域名称
        saleCityUuid: item.cityCode, // 销售城市编码
        saleCityName: item.cityName, // 销售城市名称
        saleProvinceUuid: item.provinceCode, // 销售省编码
        saleProvinceName: item.provinceName, // 销售省名称
        templateCityUuid: item.cityCode, // 参照城市编码（默认初始参照自己销售城市）
        templateCityName: item.cityName, // 参照城市名称
        buyPriceRatio: null, // 进价比例
        costPriceRatio: null, // 成本价比例
      }))
      return initList
    },
    // 获取参照相关信息
    getTemplateCityInfo (item) {
      const referCanSupply = this.supplyCityCodes.includes(item.templateCityUuid) // 参照城市是否供货
      const saleCanSupply = this.supplyCityCodes.includes(item.saleCityUuid) // 销售城市是否供货
      // 参照城市为空且本销售城市可供货时，参照城市参照自己
      if (!item.templateCityUuid && this.isSupply(item))
        return { templateCityUuid: item.saleCityUuid, templateCityName: item.saleCityName, buyPriceRatio: 1, costPriceRatio: 1 }
      // 本销售城市不供货时，清空参照
      if (!saleCanSupply)
        return { templateCityUuid: '', templateCityName: '', buyPriceRatio: 1, costPriceRatio: 1 }
      // 参照自己且不供货时，参照清空，价格比例默认1
      if (this.isSelfReferenced(item) && !referCanSupply)
        return { templateCityUuid: '', templateCityName: '', buyPriceRatio: 1, costPriceRatio: 1 }
      // 参照其他城市且本销售城市可供货，则参照自己
      if (!this.isSelfReferenced(item) && this.isSupply(item))
        return { templateCityUuid: item.saleCityUuid, templateCityName: item.saleCityName, buyPriceRatio: 1, costPriceRatio: 1 }
      // 参照其他城市且参照城市不供货，且本销售城市也不供货时，参照清空，价格比例默认1
      if (!this.isSelfReferenced(item) && !referCanSupply && !this.isSupply(item))
        return { templateCityUuid: '', templateCityName: '', buyPriceRatio: 1, costPriceRatio: 1 }
      // 其余情况不做处理
      return item
    },
    // 供货城市变更更新销售城市表格数据
    updateSalesListBySupplyCities () {
      const updateSalesList = this.TableInfo.list.map(item => ({
        ...item,
        ...this.getTemplateCityInfo(item)
      }))
      this.TableInfo.setList(updateSalesList)
    },
    // 批量设置参照信息
    batchSetReferInfo (infoData) {
      const { costPriceRatio, templateCityUuid, templateCityName } = infoData ?? {}
      if (this.TableInfo.isNullSelection()) return this.$message.warning('请勾选列表后操作')
      if (!costPriceRatio && !templateCityUuid) return this.$message.warning('批量设置成本价比例和参照城市不能都为空')
      if (!costPriceRatio && templateCityUuid) return this.batchUpdateCostRatioCityList({ templateCityUuid, templateCityName })
      const updateList = this.TableInfo.list.map(item => ({
        ...item, templateCityUuid, templateCityName, costPriceRatio
      }))
      this.TableInfo.setList(updateList)
    },
    // 获取更新成本价格比例后的数据集合
    async batchUpdateCostRatioCityList ({ templateCityUuid, templateCityName }) {
      // 获取更新后的表格数据方法
      const getUpdateList = list => this.TableInfo.list.map(item => {
        const cityInfo = (list ?? []).find(el => el.saleCityUuid == item.saleCityUuid)
        if (cityInfo) return { ...item, templateCityUuid, templateCityName, costPriceRatio: cityInfo?.costPriceRatio }
        return { ...item, templateCityUuid, templateCityName, costPriceRatio: 1 }
      })
      // 销售城市不供货的设置参照城市的时候需要获取成本价比率
      const data = this.TableInfo.selection
        .filter(item => !this.isSupply(item))
        .map(item => ({ saleCityUuid: item.saleCityUuid, templateCityUuid }))
      if (data.length == 0) return this.TableInfo.setList(getUpdateList())
      const res = await getPriceRatioByAreaCodeService(data, this.TableInfo.setLoading)
      this.TableInfo.setList(getUpdateList(res?.retData))
    },
    // 确定操作校验
    validateResults () {
       // 有城市没有设置参照城市
      const hasInCompleteReferCities = this.TableInfo.list.some(item => !item.templateCityUuid)
      if (hasInCompleteReferCities) return this.$message.warning('请填写完整参照城市')
      // 有相互参照的城市
      const hasReferCityByCrossReference = this.TableInfo.list.some(
        row => row.saleCityUuid != row.templateCityUuid &&
        this.TableInfo.list.find(item => row.saleCityUuid === item.templateCityUuid)
      )
      if (hasReferCityByCrossReference) return this.$message.warning('参照城市之间不能互相参照')
      // 有价格比例不在0.6-5之间的城市
      const warnMsgs = getCityNamesByPurchaseIneligibleRatio(this.TableInfo.list)
      if (warnMsgs) return this.$message.warning(`${warnMsgs}：进价比例和成本价比例均需在0.6-5之间`)
    },
    // 确定
    handleConfirm () {
      if (this.validateResults()) return
      this.$emit('getReferList', this.TableInfo.list)
      this.handleCancel()
    },
    // 取消
    handleCancel () {
      this.$refs?.headerRef?.clearAllState()
      this.$emit('update:visible', false)
    },
    // 渲染参照城市表列
    renderReferCityCol (h, row) {
      const updateRow = async cityInfo => {
        row.templateCityUuid = cityInfo?.templateCityUuid
        row.templateCityName = cityInfo?.templateCityName
        if (!this.isSupply(row)) {
          const data = [{ saleCityUuid: row.saleCityUuid, templateCityUuid: row.templateCityUuid }]
          const res = await getPriceRatioByAreaCodeService(data, this.TableInfo.setLoading)
          row.costPriceRatio = res?.retData[0]?.costPriceRatio
        }
      }
      const listeners = { 'getCityInfo': cityInfo => { updateRow(cityInfo) }}
      return <ReferCitySelect
        value={row.templateCityUuid}
        city-options={this.referCitiesOptions}
        supply-city-codes={this.supplyCityCodes}
        on={listeners}
      />
    },
    // 渲染比例表列
    renderRatioCol (h, row, key) {
      if (this.isSelfReferenced(row)) {
        row[key] = 1
        return <span>无需维护</span>
      }
      return <InputNumber value={ row[key] } size="mini" controls={false} onChange={val => { row[key] = val } } />
    },
    // 设置销售城市表列
    setSalesCitiesColumns () {
      const columns = [
        { title: '销售城市', key: 'saleCityName' },
        { title: '销售省', key: 'saleProvinceName' },
        {
          title: '是否供货',
          render: (h, { row }) => {
            row.isSupply = this.isSupply(row) ? '1' : '2'
            return <span>{this.isSupply(row) ? '是' : '否'}</span>
          }
        },
        { title: '业务区域', key: 'saleAreaName' },
        {
          title: '参照城市',
          width: 130,
          render: (h, { row }) => this.renderReferCityCol(h, row)
        },
        {
          title: '进价比例',
          width: 150,
          render: (h, { row }) => this.renderRatioCol(h, row, 'buyPriceRatio')
        },
        {
          title: '成本价比例',
          width: 150,
          render: (h, { row }) => this.renderRatioCol(h, row, 'costPriceRatio')
        }
      ]
      this.TableInfo.setColumns(columns)
    },
  }
}
</script>
<style lang="less" scoped>
/deep/ .el-dialog__header {
  border-bottom: none
}
.footer-wrap {
  display: flex;
  justify-content: center;
  margin-top: 10px;
}
</style>
